/********************************************************************/
/*  Copyright (C) School of Software Engineering of USTC, 2012                               
/*                                                                                                                       
/*  FILE NAME: dbapi.c                                                                                          
/*  PRINCIPAL AUTHOR: SA12226114(Xin Zhu), SA12226139(Dan Shu)                    
/*  SUBSYSTEM NAME: DB                                                                                    
/*  MODULE NAME: dbapi                                                                                      
/*  LANGUAGE: C                                                                                                 
/*  TARGET ENVIRONMENT: Linux                                                                          
/*  DATE OF FIRST RELEASE: 2012-11-20                                                             
/*  DESCRIPTION: Impement of Abstract Interface for Tokyo Cabinet DB API              
/********************************************************************/



/* include private header file */
#include "tcutil.h"
#include "tchdb.h"
#include "dbapi.h"
#include "../common/common.h"


/*****************************************************************
Function Name: db_new
Description: implement a unified database initialize interface for diverse db
Parameter:  void
Author: SA12226114(Xin Zhu), SA12226139(Dan Shu)
Date: 2012-11-27
******************************************************************/
void* db_new(void)
{
    return tchdbnew();
}


/*****************************************************************
Function Name: db_open
Description: implement a unified database open interface for diverse db
Parameter:  @db: a pointer to database object
Author: SA12226114(Xin Zhu), SA12226139(Dan Shu)
Date: 2012-11-27
Comment: We don't need to check input parameters, because the corresponding 
                interface of TC has checked input parameters.
******************************************************************/
void db_open(void *db, void *dbname)
{
    int ecode;

    /* invoke open interface of TC to open a database */

    if(strlen(dbname) > 0)
    {
        if(!tchdbopen(db, dbname, HDBOWRITER | HDBOCREAT))
        {
            ecode = tchdbecode(db);
            fprintf(stderr, "open error: %s\n", tchdberrmsg(ecode));
            printf("tchdbnew() failed!\n");

            return;
        }
    }
    else
    {
        if(!tchdbopen(db, "mydb.tch", HDBOWRITER | HDBOCREAT))
        {
            ecode = tchdbecode(db);
            fprintf(stderr, "open error: %s\n", tchdberrmsg(ecode));
            printf("tchdbnew() failed!\n");

            return;
        }
    }
    

    printf("open database successfully.\n\n");
    
    return;
}


/*****************************************************************
Function Name: db_create
Description: implement a unified database creare interface for diverse db
Parameter:  
@ppdb: a pointer to database object pointer
@dbname: database name

Author: SA12226114(Xin Zhu), SA12226139(Dan Shu)
Date: 2012-11-27
Comment: 
******************************************************************/
void db_create(void **ppdb, void *dbname)
{
    
    if(*ppdb)
    {
        printf("database has been opened!\n\n");
    }
    else
    {
        /* create the db object */
        *ppdb = db_new();
        
        /* open the database */
        db_open(*ppdb, dbname);
    }

    return;
}


/*****************************************************************
Function Name: db_write
Description: implement a unified database write interface for diverse db
Parameter:  
@db: a pointer to database object
@key: a pointer to key 
@value: a pointer to value

Author: SA12226114(Xin Zhu), SA12226139(Dan Shu)
Date: 2012-11-27
******************************************************************/
void db_write(void *db, char *key, char *value)
{
    int ecode;

    if(!db)
    {
        printf("database has not been created!\n\n");

        return;
    }

    /* invoke put interface of TC to write pairs of key and value into database */
    if(!tchdbput2(db, key, value))
    {
        ecode = tchdbecode(db);
        fprintf(stderr, "put error: %s\n", tchdberrmsg(ecode));
        printf("set fail\n");

        return;
    }

    printf("set value successfully.\n\n");

    return;
}


/*****************************************************************
Function Name: db_read
Description: implement a unified database read interface for diverse db
Parameter:  
@db: a pointer to database object
@key: a pointer to key 
@void *: a pointer to return value

Author: SA12226114(Xin Zhu), SA12226139(Dan Shu)
Date: 2012-11-27
******************************************************************/
void db_read(void *db, char *key, char *retval)
{
    char *value;
    int ecode;
    
    if(!db)
    {
        printf("database has not been created!\n\n");

        return;
    }

    /* invoke get interface of TC to read value from database in according to key */
    value = tchdbget2(db, key);
    strncpy(retval, value, strlen(value));
    printf("value = %s\n\n", value);
    free(value);
    
    return;
}


/*****************************************************************
Function Name: db_remove
Description: implement a unified database remove interface for a specific record
Parameter:  
@db: a pointer to database object
@key: a pointer to key 

Author: SA12226114(Xin Zhu), SA12226139(Dan Shu)
Date: 2012-11-27
******************************************************************/
void db_remove(void *db, char *key)
{
    int ecode;
    
    if(!db)
    {
        printf("database has not been created!\n\n");

        return;
    }

    /* invoke get interface of TC to read value from database in according to key */
    if(!tchdbout2(db, key))
        printf("remove (key = %s) is not successful.\n\n", key);
    
    return;
}


/*****************************************************************
Function Name: db_queryallrecords
Description: dump all records
Parameter:  
@db: a pointer to database object

Author: SA12226114(Xin Zhu), SA12226139(Dan Shu)
Date: 2012-11-27
Comment: 
******************************************************************/
void db_queryallrecords(void *db)
{
    char *key, *value;
    int index;

    if(!db)
    {
        printf("database has not been created!\n\n");

        return;
    }
                
    /* traverse records */
    tchdbiterinit(db);
    while((key = tchdbiternext2(db)) != NULL)
    {
        value = tchdbget2(db, key);
        if(value)
        {
            printf("key = %s", key);
            for(index = 0; index < (KEY_LEN - strlen(key)); index++)
                printf(" ");
            printf("|");
            printf("value = %s\n", value);
            free(value);
        }
        free(key);
    }

    printf("\n");
    
    return;
}


/*****************************************************************
Function Name: db_close
Description: implement a unified database close interface for diverse db
Parameter: @ppdb: a pointer to database object pointer
Author: SA12226114(Xin Zhu), SA12226139(Dan Shu)
Date: 2012-11-27
******************************************************************/
void db_close(void **ppdb)
{
    int ecode;
    
    if(!(*ppdb))
    {
        printf("database has not been created!\n\n");

        return;
    }

    /* invoke close interface of TC to close database  */
    if(!tchdbclose(*ppdb))
    {
        ecode = tchdbecode(*ppdb);
        fprintf(stderr, "close error: %s\n", tchdberrmsg(ecode));

        return;
    }

    *ppdb = NULL;
    printf("close database successfully.\n\n");

    return;
}


/*****************************************************************
Function Name: db_delete
Description: implement a unified database delete interface for diverse db
Parameter: @ppdb: a pointer to database object pointer
Author: SA12226114(Xin Zhu), SA12226139(Dan Shu)
Date: 2012-11-27
******************************************************************/
void db_delete(void **ppdb)
{
    if(!(*ppdb))
    {
        printf("database has not been created!\n\n");

        return;
    }
    
    /* invoke delete interface of TC to delete database object  */
    tchdbdel(*ppdb);

    *ppdb = NULL;
    
    printf("delete database successfully.\n\n");

    return;
}


